#include <stdio.h>
#include <unistd.h>

#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_pwm.h"
#include "ohos_init.h"
#include "app_pwm.h"
#include "app_log.h"

const static char *TAG = "app_pwm.c";

#define LED_GPIO 2
#define PWM_CHANGE_TIMES 100
#define PWM_FREQ 4000
#define PWM_DELAY_10US 10
#define DEL NULL
typedef void (*pwm_func)(uint8_t,...);

/**
 * @brief pwmIO_init
 *
 * @param uint8_t pwm_gpio 
 * @param uint8_t pwm_gpio_func
 */
void pwmIO_init(uint8_t pwm_gpio,uint8_t pwm_gpio_func)
{
    unsigned int ret;
    // init gpio of LED
    ret = IoTGpioInit(pwm_gpio);
    if (ret != 0) 
    {
        MY_LOGI(TAG,"IoTGpioInit failed!\r\n");
        return;
    }
    // set the GPIO_2 multiplexing function to PWM
    ret = IoTGpioSetFunc(pwm_gpio, pwm_gpio_func);
    if (ret != 0) 
    {
        MY_LOGI(TAG,"IoTGpioSetFunc failed!\r\n");
        return;
    }
    // set GPIO_2 is output mode
    ret = IoTGpioSetDir(pwm_gpio, IOT_GPIO_DIR_OUT);
    if (ret != 0) 
    {
        MY_LOGI(TAG,"IoTGpioSetDir failed!\r\n");
        return;
    }
    // init PWM2
    ret = IoTPwmInit(pwm_gpio);
    if (ret != 0) 
    {
        MY_LOGI(TAG,"IoTPwmInit failed!\r\n");
        return;
    }
}

/**
 * @brief pwm_ctrl
 * 
 * @param uint8_t pwm_gpio
 * @param uint8_t duty(0-100)
 */
void pwm_ctrl(uint8_t pwm_gpio,uint8_t duty)
{
    IoTPwmStart(pwm_gpio, duty, PWM_FREQ);
}

/**
 * @brief pwm_test_task
 *
 */
void pwm_test_task(void)
{
    unsigned int i;
    
    pwm_func io_mode_init;
    io_mode_init = pwmIO_init;
    (*io_mode_init)(LED_GPIO,IOT_GPIO_FUNC_GPIO_2_PWM2_OUT);
    io_mode_init = DEL;

    while (1)
    {
        for (i = 0; i < PWM_CHANGE_TIMES; i++)
        {
            // output PWM with different duty cycle
            IoTPwmStart(LED_GPIO, i, PWM_FREQ);
            usleep(PWM_DELAY_10US);
        }
        for (i = PWM_CHANGE_TIMES; i > 0; i--) 
        {
            // output PWM with different duty cycle
            IoTPwmStart(LED_GPIO, i, PWM_FREQ);
            usleep(PWM_DELAY_10US);
        }
        i = 0;
    }
}

